21 文件缓存
系统调用层和虚拟文件系统层
系统函数 read 和 write
- read : 调用 vfs_read->__vfs_read
- write:调用 vfs_write->__vfs_write
ext4 文件系统层
调用 ext4_file_read_iter 和 ext4_file_write_iter
- ext4_file_read_iter 调用 generic_file_read_iter
- ext4_file_write_iter 调用 __generic_file_write_iter
缓存其实就是内存中的一块空间。
缓存 I/O:大多数文件系统的默认 I/O 操作都是缓存 I/O。读操作来先检查,内核的缓冲区有没有需要的数据。如果已经缓存了,就直接从缓存中返回;否则从磁盘中读取,然后缓存在操作系统的缓存中。
直接 IO:应用程序直接访问磁盘数据,而不经过内核缓冲区,从而减少了在内核缓存和用户程序之间数据复制。
带缓存的写入操作
对于每一页,先调用 address_space 的 write_begin 做一些准备;
- 调用 iov_iter_copy_from_user_atomic,将写入的内容从用户态拷贝到内核态的页中;
- 调用 address_space 的 write_end 完成写操作;
- 调用 balance_dirty_pages_ratelimited,看脏页是否太多,需要写回硬盘。脏页即写入到缓存,但是还没有写入到硬盘的页面。
带缓存的读操作
generic_file_buffered_read 函数找到 page cache 里面是否有缓存页,如果没找到,读取这一页并进行预读,然后查找缓存页。如果找到了,要判断是不是应该继续预读;如果需要,就调用 page_cache_async_readahead 发起一个异步预读。最后,copy_page_to_iter 会将内容从内核缓存页拷贝到用户内存空间。